/**
 *
 */
package com.jhf.youke.core.utils;

import org.apache.commons.lang3.time.DateFormatUtils;

import java.math.BigDecimal;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * 日期工具类, 继承org.apache.commons.lang.time.DateUtils类
 *
 * @author ThinkGem
 * @version 2014-4-15
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
	public static final String YYYY_MM_DD = "yyyyMMdd";
	public static final String YYYY_MM_DD_HH_MM_SS = "yyyyMMddHHmmss";

	/** 紧凑型日期格式，也就是纯数字类型yyyyMMdd **/
	public static final DateUtils COMPAT = new DateUtils(new SimpleDateFormat("yyyyMMdd"));

	/**  常用日期格式，yyyy-MM-dd **/
	public static final DateUtils COMMON = new DateUtils(new SimpleDateFormat("yyyy-MM-dd"));
	public static final DateUtils COMMON_FULL = new DateUtils(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

	/** 使用斜线分隔的，西方多采用，yyyy/MM/dd **/
	public static final DateUtils SLASH = new DateUtils(new SimpleDateFormat("yyyy/MM/dd"));

	/** 中文日期格式常用，yyyy年MM月dd日 **/
	public static final DateUtils CHINESE = new DateUtils(new SimpleDateFormat("yyyy年MM月dd日"));
	public static final DateUtils CHINESE_FULL = new DateUtils(new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"));

	private final SimpleDateFormat format;

	private static final ThreadLocal<SimpleDateFormat> THREAD_LOCAL = new ThreadLocal<>(){
		@Override
		protected SimpleDateFormat initialValue() {
			return new SimpleDateFormat();
		}
	};

	public DateUtils(SimpleDateFormat format) {
		this.format = format;
	}

	private static final String[] PARSE_PATTERNS = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
			"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss",
			"yyyy.MM.dd HH:mm", "yyyy.MM", "yyyyMMddHHmmss", "yyyyMMdd", "yyyyMM" };

	/**
	 * 得到当前日期字符串 格式（yyyy-MM-dd）
	 */
	public static String getDate() {
		return getDate("yyyy-MM-dd");
	}

	/**
	 * 得到当前日期
	 */
	public static Date getCurrentDate() {
		Date d = new Date(System.currentTimeMillis());
		return d;
	}

	/**
	 * 得到当前日期字符串
	 */
	public static String getCurrentDateStr() {
		return getDateText(getCurrentDate(),"yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 日期获取字符串
	 */
	public String getDateText(Date date) {
		return THREAD_LOCAL.get().format(date);
	}

	/**
	 * 字符串获取日期
	 *
	 * @throws ParseException
	 */
	public Date getTextDate(String text) throws ParseException {
		return THREAD_LOCAL.get().parse(text);
	}

	/**
	 * 日期获取字符串
	 */
	public static String getDateText(Date date, String format) {
		return new SimpleDateFormat(format).format(date);
	}

	/**
	 * 字符串获取日期
	 *
	 * @throws ParseException
	 */
	public static Date getTextDate(String dateText, String format) throws ParseException {
		return new SimpleDateFormat(format).parse(dateText);
	}


	/**计算两个时间差得出：时分秒 **/
	public static   String getMinute(LocalDateTime createTime, LocalDateTime endTime) {
		Duration duration = Duration.between(createTime, endTime);
		long hour = duration.getSeconds() / ChronoUnit.HOURS.getDuration().getSeconds();
		long minute = (duration.getSeconds() - ChronoUnit.HOURS.getDuration().getSeconds() * hour) / ChronoUnit.MINUTES.getDuration().getSeconds();
		long second = (duration.getSeconds() - ChronoUnit.HOURS.getDuration().getSeconds() * hour) - minute * ChronoUnit.MINUTES.getDuration().getSeconds();
		return hour + ":" + minute + ":" + second;
	}

	/** Date转换为LocalDateTime **/
	public static LocalDateTime convertDateToLocalDateTime(Date date) {
		return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
	}



	/**
	 * 取当前月份第一天第一秒
	 */
	public static Date getCurrentMonthFirst() throws ParseException {

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd ");
		// 获取当前月第一天：
		Calendar c = Calendar.getInstance();
		c.add(Calendar.MONTH, 0);
		// 设置为1号,当前日期既为本月第一天
		c.set(Calendar.DAY_OF_MONTH, 1);
		String first = format.format(c.getTime());

		return format.parse(first + " 00:00:00");
	}

	public static String getCurrentMonthFristString() throws ParseException {

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd ");

		// 获取当前月第一天：
		Calendar c = Calendar.getInstance();
		c.add(Calendar.MONTH, 0);
		// 设置为1号,当前日期既为本月第一天
		c.set(Calendar.DAY_OF_MONTH, 1);
		String first = format.format(c.getTime());

		return first + "00:00:00";
	}


	/**
	 * 取当前日期的加上时间
	 */
	public static Date addTime(Date date, String time) throws ParseException {


		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
		String str=sdf.format(date);

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return format.parse(str + " "+ time );
	}



	/**
	 * 取当前月份第最后天最后一秒
	 */
	public static Date getCurrentMonthLast() throws ParseException {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd ");
		// 获取当前月最后一天
		Calendar ca = Calendar.getInstance();
		ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
		String last = format.format(ca.getTime());
		format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return format.parse(last + " 23:59:59");
	}


	public static String getCurrentMonthLastString() throws ParseException {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd ");
		// 获取当前月最后一天
		Calendar ca = Calendar.getInstance();
		ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
		String last = format.format(ca.getTime());
		format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return last + "23:59:59";
	}

	/**
	 * 用于一个日期，增加天数后，返回一个增加的日期
	 **/
	public static Date addDate(Date date, int day) {
		Date d = new Date();

		Calendar ca = Calendar.getInstance();
		ca.setTime(date);
		ca.add(Calendar.DATE, day);
		d = ca.getTime();

		return d;
	}

	/**
	 * 用于一个Time类型时间，增加分钟后，返回一个Time类型时间
	 **/
	public static Time addTime(String date, int minute) throws ParseException {
		Time time = null;
		String[] obj = date.split(":");
		int h = Integer.valueOf(obj[0]);
		int m = Integer.valueOf(obj[1]);

		String hour = h < 10 ? "0" + h : "" + h;
		String min = m < 10 ? "0" + m : "" + m;

		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

		Date d1 = sdf.parse(hour + ":" + min + ":00");

		Calendar ca = Calendar.getInstance();
		ca.setTime(d1);
		ca.add(Calendar.MINUTE, minute);
		time = Time.valueOf(sdf.format(ca.getTime()));

		return time;
	}

	public static Date addDate(Date date, int day, String pattern) {
		Date d = new Date();
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		format.format(date);

		Calendar ca = Calendar.getInstance();
		ca.add(Calendar.DATE, day);
		d = ca.getTime();

		return d;
	}

	/**
	 * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
	 */
	public static String getDate(String pattern) {
		return DateFormatUtils.format(new Date(), pattern);
	}

	/**
	 * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
	 */
	public static String formatDate(Date date, Object... pattern) {
		String formatDate ;
		if (pattern != null && pattern.length > 0) {
			formatDate = DateFormatUtils.format(date, pattern[0].toString());
		} else {
			formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
		}
		return formatDate;
	}

    /**
     * 格式化长整型时间
     * @param timeMillions
     * @param pattern
     * @return
     */
	public static String formateTime(Long timeMillions, String pattern) {
		return StringUtils.isEmpty(pattern) ?
				DateFormatUtils.format(timeMillions, "yyyyMMddHHmmss")
				: DateFormatUtils.format(timeMillions, pattern);
	}

	/**
	 * 两个日期天数比较 正数为大于，0为等于，负数为小于 BY RHJ
	 **/
	public static int compare(Date date1, Date date2) {
		int day = 0;
		Calendar aCalendar = Calendar.getInstance();
		aCalendar.setTime(date1);
		int day1 = aCalendar.get(Calendar.DAY_OF_YEAR);
		aCalendar.setTime(date2);
		int day2 = aCalendar.get(Calendar.DAY_OF_YEAR);
		day = day1 - day2;
		return day;
	}

	public static int compareMonth(Date date1, Date date2) {
		int day = 0;
		Calendar aCalendar = Calendar.getInstance();
		aCalendar.setTime(date1);
		int day1 = aCalendar.get(Calendar.MONTH);
		aCalendar.setTime(date2);
		int day2 = aCalendar.get(Calendar.MONTH);
		day = day1 - day2;
		return day;
	}

	/**
	 * 得到日期时间字符串，转换格式（yyyy-MM-dd HH:mm:ss）
	 */
	public static String formatDateTime(Date date) {
		return formatDate(date, "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 得到当前时间字符串 格式（HH:mm:ss）
	 */
	public static String getTime() {
		return formatDate(new Date(), "HH:mm:ss");
	}

	/**
	 * 得到当前日期和时间字符串 格式（yyyy-MM-dd HH:mm:ss）
	 */
	public static String getDateTime() {
		return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 得到当前年份字符串 格式（yyyy）
	 */
	public static String getYear() {
		return formatDate(new Date(), "yyyy");
	}

	/**
	 * 得到当前月份字符串 格式（MM）
	 */
	public static String getMonth() {
		return formatDate(new Date(), "MM");
	}

	/**
	 * 得到当天字符串 格式（dd）
	 */
	public static String getDay() {
		return formatDate(new Date(), "dd");
	}

	/**
	 * 得到当前星期字符串 格式（E）星期几
	 */
	public static String getWeek() {
		return formatDate(new Date(), "E");
	}

	/**
	 * 得到当前年份月字符串 格式（yyyy）
	 */
	public static String getYearMonth() {
		return formatDate(new Date(), "yyyyMM");
	}

	/**
	 * 日期型字符串转化为日期 格式 { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
	 * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy.MM.dd",
	 * "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm" }
	 */
	public static Date parseDate(Object str) {
		if (str == null) {
			return null;
		}
		try {
			return parseDate(str.toString(), PARSE_PATTERNS);
		} catch (ParseException e) {
			return null;
		}
	}

	public static Timestamp parseTime(Object str) {
		if (str == null) {
			return null;
		}

		Date date = null;
		try {
			date = parseDate(str.toString(), "HH:mm:ss");
		} catch (ParseException e) {
			return null;
		}

		return new Timestamp(date.getTime());
	}

	/**
	 * 获取过去的天数
	 *
	 * @param date
	 * @return
	 */
	public static long pastDays(Date date) {
		long t = System.currentTimeMillis() - date.getTime();
		return t / (24 * 60 * 60 * 1000);
	}

	/**
	 * 获取过去的小时
	 *
	 * @param date
	 * @return
	 */
	public static long pastHour(Date date) {
		long t = System.currentTimeMillis() - date.getTime();
		return t / (60 * 60 * 1000);
	}

	/**
	 * 获取过去的分钟
	 *
	 * @param date
	 * @return
	 */
	public static long pastMinutes(Date date) {
		long t = System.currentTimeMillis() - date.getTime();
		return t / (60 * 1000);
	}

	/**
	 * 转换为时间（天,时:分:秒.毫秒）
	 *
	 * @param timeMillis
	 * @return
	 */
	public static String formatDateTime(long timeMillis) {
		long day = timeMillis / (24 * 60 * 60 * 1000);
		long hour = (timeMillis / (60 * 60 * 1000) - day * 24);
		long min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
		long s = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
		long sss = (timeMillis - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000 - min * 60 * 1000 - s * 1000);
		return (day > 0 ? day + "," : "") + hour + ":" + min + ":" + s + "." + sss;
	}

	/**
	 * 获取两个日期之间的天数
	 *
	 * @param before
	 * @param after
	 * @return
	 */
	public static double getDistanceOfTwoDate(Date before, Date after) {
		long beforeTime = before.getTime();
		long afterTime = after.getTime();
		return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
	}

	/**
	 * 获取两个日期之间的小时
	 *
	 * @param before
	 * @param after
	 * @return
	 */
	public static double getHouseDistanceOfTwoDate(Date before, Date after) {
		long beforeTime = before.getTime();
		long afterTime = after.getTime();
		return (afterTime - beforeTime) / (1000 * 60 * 60);
	}

	/**
	 * 根据日期String,时间String 设置时间
	 **/
	public static Date setDateTime(String date, String time) throws ParseException {

		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		Date d = dateFormat.parse(date + " " + time);

		return d;
	}

	/**
	 * 根据年 月 获取对应的月份 天数
	 */
	public static int getDaysByYearMonth(int year, int month) {
		Calendar a = Calendar.getInstance();
		a.set(Calendar.YEAR, year);
		a.set(Calendar.MONTH, month - 1);
		a.set(Calendar.DATE, 1);
		a.roll(Calendar.DATE, -1);
		int maxDate = a.get(Calendar.DATE);
		return maxDate;
	}

	/**
	 * 根据当前时间获取当前月份 天数
	 */

	public static int getDaysByYearMonth() {
		Date date = new Date(System.currentTimeMillis());
		Calendar a = Calendar.getInstance();
		a.setTime(date);
		a.set(Calendar.DATE, 1);
		a.roll(Calendar.DATE, -1);
		int maxDate = a.get(Calendar.DATE);
		return maxDate;
	}

	/**
	 * 计算 second 秒后的时间
	 *
	 * @param date
	 * @param second
	 * @return
	 */
	public static Date addSecond(Date date, int second) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.SECOND, second);
		return calendar.getTime();
	}

	/**
	 * 计算 minute 分钟后的时间
	 *
	 * @param date
	 * @param minute
	 * @return
	 */
	public static Date addMinute(Date date, int minute) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MINUTE, minute);
		return calendar.getTime();
	}

	/**
	 * 计算 hour 小时后的时间
	 *
	 * @param date
	 * @param hour
	 * @return
	 */
	public static Date addHour(Date date, int hour) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.HOUR, hour);
		return calendar.getTime();
	}

	/**
	 * 得到day的起始时间点。
	 *
	 * @param date
	 * @return
	 */
	public static Date getDayStart(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 得到day的终止时间点.
	 *
	 * @param date
	 * @return
	 */
	public static Date getDayEnd(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		calendar.add(Calendar.DAY_OF_MONTH, 1);
		calendar.add(Calendar.MILLISECOND, -1);
		return calendar.getTime();
	}

	public static boolean isSameDayWithToday(Date date) {

		if (date == null) {
			return false;
		}

		Calendar todayCal = Calendar.getInstance();
		Calendar dateCal = Calendar.getInstance();

		todayCal.setTime(new Date());
		dateCal.setTime(date);
		int subYear = todayCal.get(Calendar.YEAR) - dateCal.get(Calendar.YEAR);
		int subMouth = todayCal.get(Calendar.MONTH) - dateCal.get(Calendar.MONTH);
		int subDay = todayCal.get(Calendar.DAY_OF_MONTH) - dateCal.get(Calendar.DAY_OF_MONTH);
		if (subYear == 0 && subMouth == 0 && subDay == 0) {
			return true;
		}
		return false;
	}


	/**
	 * 判断日期是星期几
	 * @param pTime
	 * @return
	 * @throws Exception
	 */
	public static String dayForWeek(String pTime) throws Exception {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date tmpDate = format.parse(pTime);
		Calendar cal = Calendar.getInstance();
		String[] weekDays = { "7", "1", "2", "3", "4", "5", "6" };
		try {
			cal.setTime(tmpDate);
		} catch (Exception e) {
			e.getMessage();
		}
		// 指示一个星期中的某天。
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0){
			w = 0;
		}

		return weekDays[w];
	}

	/**
	 * @param args
	 * @throws ParseException
	 */
	public static void main(String[] args) throws Exception {
//		String a = "☀";
//		String b = gbEncoding(a);
//		System.out.println(b);
//
//		String c = decodeUnicode(b);
//		System.out.println(dayForWeek("2021-03-16"));
		// System.out.println(getDate("yyyy年MM月dd日 E"));
		// long time = new Date().getTime()-parseDate("2012-11-19").getTime();
		// System.out.println(time/(24*60*60*1000));
	}
	/**
	 * 中文转unicode编码
	 **/
	public static String gbEncoding(final String gbString) {
		char[] utfBytes = gbString.toCharArray();
		String unicodeBytes = "";
		for (int i = 0; i < utfBytes.length; i++) {
			String hexB = Integer.toHexString(utfBytes[i]);
			if (hexB.length() <= 2) {
				hexB = "00" + hexB;
			}
			unicodeBytes = unicodeBytes + "\\u" + hexB;
		}
		return unicodeBytes;
	}
	/**
	 * unicode编码转中文
	 **/
	public static String decodeUnicode(final String dataStr) {
		int start = 0;
		int end = 0;
		final StringBuffer buffer = new StringBuffer();
		while (start > -1) {
			end = dataStr.indexOf("\\u", start + 2);
			String charStr = "";
			if (end == -1) {
				charStr = dataStr.substring(start + 2, dataStr.length());
			} else {
				charStr = dataStr.substring(start + 2, end);
			}
			// 16进制parse整形字符串。
			char letter = (char) Integer.parseInt(charStr, 16);
			buffer.append(letter);
			start = end;
		}
		return buffer.toString();
	}

	public static void aa(){

		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();

		Map<String, Object> map1 = new HashMap<String, Object>(8);
		map1.put("id", "1");
		map1.put("probability", 0.7);

		Map<String, Object> map2 = new HashMap<String, Object>(8);
		map2.put("id", "2");
		map2.put("probability", 0.3);

		list.add(map1);
		list.add(map2);

		int randomNumber = 71;
		System.out.println("中奖数：" + randomNumber);
		int min = 0;
		for(Map<String, Object> item:list){
			BigDecimal probability = new BigDecimal(item.get("probability").toString());
			int b = probability.multiply(new BigDecimal(100)).intValue();
			int max = min + b;
			if(randomNumber > min &&  randomNumber <= max){
				System.out.println("中奖ID：" + item.get("id").toString());
				break;
			}
			min = max;
		}
//		System.out.println(dayForWeek("2021-03-16"));
		// System.out.println(getDate("yyyy年MM月dd日 E"));
		// long time = new Date().getTime()-parseDate("2012-11-19").getTime();
		// System.out.println(time/(24*60*60*1000));
	}
}
